fix(web): expose Codex Fast and Plan on Create Session#1017
Conversation
Wire serviceTier and collaborationMode through spawn so Create can set the same Codex options chat Settings already supports (tiann#1015). Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Findings
- [Major]
collaborationModeis dropped before the runner sees it — the hub now includescollaborationModein the machine RPC payload, but the CLI machine RPC handler still only destructures and forwards the older fields. A Create Session request with Collaboration = Plan will therefore spawnhapi codexwithout--collaboration-mode plan, so the new selector has no effect. Evidence:hub/src/sync/rpcGateway.ts:162; receiver context:cli/src/api/apiMachine.ts:262andcli/src/api/apiMachine.ts:273.
Suggested fix:const { directory, sessionId, resumeSessionId, machineId, approvedNewDirectoryCreation, agent, model, effort, modelReasoningEffort, yolo, permissionMode, serviceTier, collaborationMode, token, sessionType, worktreeName } = params || {} const result = await spawnSession({ directory, sessionId, resumeSessionId, machineId, approvedNewDirectoryCreation, agent, model, effort, modelReasoningEffort, yolo, permissionMode, serviceTier, collaborationMode, token, sessionType, worktreeName })
Summary
- Review mode: initial
- Found one Major issue in the new spawn plumbing: Plan mode is accepted by web/hub but lost at the CLI machine RPC boundary.
Testing
- Not run (automation; static review only).
HAPI Bot
| effort, | ||
| permissionMode, | ||
| serviceTier, | ||
| collaborationMode |
There was a problem hiding this comment.
[MAJOR] collaborationMode is added to the machine RPC payload here, but the CLI receiver still drops it: cli/src/api/apiMachine.ts destructures serviceTier but not collaborationMode, and the subsequent spawnSession({ ... }) call also omits it. That means Create Session → Collaboration = Plan reaches the hub but never becomes --collaboration-mode plan in buildCliArgs.
Suggested fix:
const { directory, sessionId, resumeSessionId, machineId, approvedNewDirectoryCreation, agent, model, effort, modelReasoningEffort, yolo, permissionMode, serviceTier, collaborationMode, token, sessionType, worktreeName } = params || {}
const result = await spawnSession({
directory,
sessionId,
resumeSessionId,
machineId,
approvedNewDirectoryCreation,
agent,
model,
effort,
modelReasoningEffort,
yolo,
permissionMode,
serviceTier,
collaborationMode,
token,
sessionType,
worktreeName
})Create Session Plan was accepted by the hub but dropped in apiMachine before buildCliArgs; also preserve collaborationMode on resume spawn. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Fixed HAPI Bot Major: |
Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Findings
- [Minor] Fast mode selection can be reset while the Codex model catalog is still loading —
showCodexFastModeis false whenevercodexModelsState.modelsis empty, including the initial load. In the Browse → New Session remount path, the draft restoresserviceTier: 'fast', then this effect immediately changes it back tostandardbeforeuseCodexModelsreturns, so the spawn payload omits Fast even for models that advertise it. Evidenceweb/src/components/NewSession/index.tsx:217.
Suggested fix:const hasCodexModelCatalog = codexModelsState.models.length > 0 useEffect(() => { if (hasCodexModelCatalog && !showCodexFastMode && serviceTier !== 'standard') { setServiceTier('standard') } }, [hasCodexModelCatalog, showCodexFastMode, serviceTier])
Summary
Review mode: follow-up after new commits
- Previous bot finding is fixed in the new commits; one remaining Minor issue affects preserving Fast mode during create-session draft restore.
Testing
- Not run (automation; static review only).
HAPI Bot
| && codexModelAdvertisesFastTier(model === 'auto' ? null : model, codexModelsState.models) | ||
|
|
||
| useEffect(() => { | ||
| if (!showCodexFastMode && serviceTier !== 'standard') { |
There was a problem hiding this comment.
[MINOR] showCodexFastMode is false while useCodexModels is still loading because the catalog array is empty. In the Browse → New Session remount path, the draft can restore serviceTier: 'fast' and then this effect immediately resets it to standard before the catalog response arrives, so the create request later omits Fast even for a model that advertises it.
Suggested fix:
const hasCodexModelCatalog = codexModelsState.models.length > 0
useEffect(() => {
if (hasCodexModelCatalog && !showCodexFastMode && serviceTier !== 'standard') {
setServiceTier('standard')
}
}, [hasCodexModelCatalog, showCodexFastMode, serviceTier])Co-authored-by: Cursor <cursoragent@cursor.com>
|
Addressed follow-up Minor: do not clear restored |
There was a problem hiding this comment.
Findings
- No issues found in the latest diff.
Summary
Review mode: follow-up after new commits
- Reviewed the full current PR diff, using the prior HAPI Bot review and
c1f81f8...9fe3fe9compare diff as follow-up context. - The prior Fast-mode restore issue appears addressed by waiting for the Codex model catalog load before clearing
serviceTier. - Residual risk: static review only; local test execution was unavailable in this environment.
Testing
- Not run:
bunis not installed in this runner environment (/bin/bash: bun: command not found).
HAPI Bot
There was a problem hiding this comment.
Findings
- No issues found in the latest diff.
Summary
Review mode: follow-up after new commits
- Reviewed the full current PR diff, using the previous HAPI Bot review and the
9fe3fe9...d8a1898compare diff as follow-up context. - No high-confidence correctness, security, regression, data-loss, performance, or maintainability issues found in the added/modified lines.
- Residual risk: static review only; focused route/UI behavior still depends on CI or a local Bun environment.
Testing
- Not run (automation):
bunis not installed in this runner environment.
HAPI Bot
…st-personality-plan # Conflicts: # cli/src/api/apiMachine.test.ts # hub/src/web/routes/machines.ts # web/src/api/client.ts # web/src/components/NewSession/index.tsx # web/src/components/NewSession/newSessionFormDraft.ts # web/src/components/NewSession/types.ts # web/src/hooks/mutations/useSpawnSession.ts
There was a problem hiding this comment.
Findings
- [Minor] Fast selection can be dropped while the Codex catalog is loading —
showCodexFastModeis false whileuseCodexModelsis still loading because the model list is empty, but the Create button remains enabled. A restored Browse draft can already haveserviceTier === 'fast'; clicking Create before the catalog settles reachesweb/src/components/NewSession/index.tsx:658withshowCodexFastMode === false, so the spawn payload omitsserviceTierand starts Standard instead of the restored Fast choice.
Suggested fix:const fastModeSelectionPending = agent === 'codex' && serviceTier === 'fast' && codexModelsState.isLoading const canCreate = Boolean( machineId && trimmedDirectory && !isFormDisabled && !missingWorktreeDirectory && !fastModeSelectionPending )
Summary
Review mode: follow-up after new commits
- Reviewed the full current PR diff, using the previous HAPI Bot review and the prior-commit compare diff as follow-up context.
- Found one static correctness issue in the new Create Session Fast-mode flow.
- Residual risk: static review only; runtime UI behavior still depends on CI or manual browser validation.
Testing
- Not run (automation): PR code treated as untrusted, so this pass did not execute tests.
HAPI Bot
| const resolvedModelReasoningEffort = (agent === 'codex' || agent === 'opencode') && modelReasoningEffort !== 'default' | ||
| ? modelReasoningEffort | ||
| : undefined | ||
| const resolvedServiceTier = agent === 'codex' && showCodexFastMode && serviceTier === 'fast' |
There was a problem hiding this comment.
[MINOR] Fast selection can be dropped while the Codex catalog is loading
showCodexFastMode is false while useCodexModels is still loading because the model list is empty, but the Create button remains enabled. A restored Browse draft can already have serviceTier === 'fast'; clicking Create before the catalog settles reaches this line with showCodexFastMode === false, so the spawn payload omits serviceTier and starts Standard instead of the restored Fast choice.
Suggested fix:
const fastModeSelectionPending = agent === 'codex'
&& serviceTier === 'fast'
&& codexModelsState.isLoading
const canCreate = Boolean(
machineId
&& trimmedDirectory
&& !isFormDisabled
&& !missingWorktreeDirectory
&& !fastModeSelectionPending
)There was a problem hiding this comment.
Findings
- No findings.
Summary
Review mode: follow-up after new commits
- Reviewed the full current PR diff, with the previous HAPI Bot review and the prior-commit compare diff as follow-up context.
- The prior Fast-mode loading race appears addressed in the current head.
- Residual risk: static review only; no runtime UI validation or test execution in this automation pass.
Testing
- Not run (automation): PR code treated as untrusted, so this pass did not execute tests.
HAPI Bot
…st-personality-plan # Conflicts: # cli/src/api/apiMachine.ts # cli/src/runner/buildCliArgs.test.ts # hub/src/sync/rpcGateway.ts # hub/src/sync/syncEngine.ts # web/src/components/NewSession/index.tsx
There was a problem hiding this comment.
Findings
- [Major] Codex import ignores the new Fast/Plan selections — the form now exposes
serviceTierandcollaborationMode, but the selected-Codex-session branch callssyncCodexSession/resumeSessionwithout either value, so choosing an existing Codex thread and pressing Create silently starts it with the stored/default tier and collaboration mode instead of the visible selections. Evidence:web/src/components/NewSession/index.tsx:769computes the selected collaboration mode, while the import branch atweb/src/components/NewSession/index.tsx:775only sends model/reasoning/yolo.
Suggested fix:// Include these in CodexDesktopSyncRequest/parseSyncSessionRequest/importSelectedCodexSessions, // then persist them on the inactive imported session before resume. const result = await props.api.syncCodexSession({ sessionIds: [selectedCodexImportSession.id], cwd: selectedCodexImportSession.cwd ?? trimmedDirectory, machineId: codexImportMachineId ?? machineId, model: resolvedModel ?? null, modelReasoningEffort: resolvedModelReasoningEffort ?? null, yolo: yoloMode, serviceTier: resolvedServiceTier ?? undefined, collaborationMode: resolvedCollaborationMode ?? undefined })
Summary
Review mode: follow-up after new commits
- Reviewed the full current PR diff plus the previous bot review context.
- Found one user-visible gap in the Codex import path for the newly exposed Create Session controls.
Testing
- Not run (automation): PR code treated as untrusted, so this pass did not execute tests.
HAPI Bot
| const resolvedServiceTier = agent === 'codex' && showCodexFastMode && serviceTier === 'fast' | ||
| ? 'fast' as const | ||
| : undefined | ||
| const resolvedCollaborationMode = agent === 'codex' && collaborationMode !== 'default' |
There was a problem hiding this comment.
[MAJOR] These new selections are ignored in the existing-Codex-session path. When selectedCodexImportSession is set, handleCreate enters the import branch below and calls syncCodexSession/resumeSession with model, reasoning effort, and yolo only, so a user can select Plan/Fast in this form and still resume the imported thread with the stored/default collaboration mode and service tier.
Suggested fix:
// Include these in CodexDesktopSyncRequest/parseSyncSessionRequest/importSelectedCodexSessions,
// then persist them on the inactive imported session before resume.
const result = await props.api.syncCodexSession({
sessionIds: [selectedCodexImportSession.id],
cwd: selectedCodexImportSession.cwd ?? trimmedDirectory,
machineId: codexImportMachineId ?? machineId,
model: resolvedModel ?? null,
modelReasoningEffort: resolvedModelReasoningEffort ?? null,
yolo: yoloMode,
serviceTier: resolvedServiceTier ?? undefined,
collaborationMode: resolvedCollaborationMode ?? undefined
})There was a problem hiding this comment.
Findings
- [Major] Create Session drops explicit Standard Fast mode — the new selector only forwards a service tier when the value is
fast, so choosing/keepingStandardproducesundefinedinstead of the explicitstandardsentinel used elsewhere. The Codex app-server mapping documentsstandard -> nullwhileundefinedmeans “omit; use account default,” and the existing chat setting sendsstandardthrough/service-tier. The import route also rejectsstandard, so fixing the client alone would fail for imported Codex threads. Evidence:web/src/components/NewSession/index.tsx:766,hub/src/web/routes/codexDesktop.ts:1706, related mapping incli/src/codex/utils/appServerConfig.ts:75.
Suggested fix:const resolvedServiceTier = agent === "codex" && showCodexFastMode ? serviceTier : undefined // create spawn serviceTier: resolvedServiceTier // Codex import payload serviceTier: resolvedServiceTier // parseSyncSessionRequest if ( hasServiceTier && bodyRecord.serviceTier !== null && bodyRecord.serviceTier !== "fast" && bodyRecord.serviceTier !== "standard" ) { return { sessionIds: [], error: "Invalid serviceTier" } }
Questions
- None.
Summary
- Review mode: follow-up after new commits
- Reviewed the full current PR diff plus the previous bot review context. The prior import Fast/Plan gap is addressed, but the new Standard Fast-mode path is still not wired as an explicit selection.
Testing
- Not run (automation). Suggested coverage: Create Codex session with Fast Mode = Standard forwards
serviceTier: "standard"; Codex import accepts/appliesserviceTier: "standard".
HAPI Bot
| const resolvedModelReasoningEffort = (agent === 'codex' || agent === 'opencode') && modelReasoningEffort !== 'default' | ||
| ? modelReasoningEffort | ||
| : undefined | ||
| const resolvedServiceTier = agent === 'codex' && showCodexFastMode && serviceTier === 'fast' |
There was a problem hiding this comment.
[MAJOR] This drops the explicit Standard Fast-mode selection. resolvedServiceTier only preserves fast; standard becomes undefined, which appServerConfig treats as “omit; use account default,” while the existing chat setting sends the explicit standard sentinel so Codex receives serviceTier: null. The import parser also needs to accept standard or the import path will reject the corrected payload.
Suggested fix:
const resolvedServiceTier = agent === "codex" && showCodexFastMode
? serviceTier
: undefined
// create spawn
serviceTier: resolvedServiceTier
// Codex import payload
serviceTier: resolvedServiceTier
// hub/src/web/routes/codexDesktop.ts
if (
hasServiceTier
&& bodyRecord.serviceTier !== null
&& bodyRecord.serviceTier !== "fast"
&& bodyRecord.serviceTier !== "standard"
) {
return { sessionIds: [], error: "Invalid serviceTier" }
}There was a problem hiding this comment.
Findings
- No issues found.
Questions
- None.
Summary
- Review mode: follow-up after new commits
- Reviewed the full current PR diff at d31312b plus the prior HAPI Bot review. The prior explicit
standardservice-tier gap is addressed in the follow-up diff. Residual risk: no browser/component test covers the full Create Session submit path for Fast/Plan selectors.
Testing
- Not run (automation).
HAPI Bot
Summary
SpawnSessionRequest→ hub → runner →hapi codex) to accept optionalserviceTierandcollaborationMode.serviceTiers, same as chat Settings).Personality: still blocked on #1003 / #1009 — upstream chat Settings does not expose Personality yet, so Create deliberately matches current chat Settings (Fast + Plan only). Follow-up after #1009 merges.
Test plan
serviceTierisfastbun run test -- src/commands/codex.test.ts src/runner/buildCliArgs.test.ts(cli)bun run test -- src/components/NewSession/newSessionFormDraft.test.ts(web)Made with Cursor